/*
 * Copyright 2015 泛泛o0之辈
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.jfast.framework.jdbc.orm;

import cn.jfast.framework.base.util.ErrorCode;

import java.lang.reflect.Field;
import java.sql.ParameterMetaData;
import java.sql.SQLException;

/**
 * Sql执行器
 */
public abstract class Executor extends Parser {

	/**
	 * Sql执行
	 * 
	 * @return
	 * @throws SQLException
	 * @throws IllegalAccessException
	 * @throws NoSuchFieldException
	 * @throws InstantiationException
	 */
	public Object execute() throws SQLException, IllegalAccessException,
			NoSuchFieldException, InstantiationException, SqlException {
		Object reObj = null;
		String sql = parseSql();
		ps = conn.prepareStatement(sql);
		fillPreparedStatement();
		if (returnType == void.class)
			ps.executeUpdate();
		else if (returnType == Boolean.class || returnType == Boolean.TYPE)
			reObj = ps.execute();
		else if (returnType == Integer.class || returnType == Integer.TYPE)
			reObj = ps.executeUpdate();
		else
			throw new SqlException(ErrorCode.ERROR_RETURN_TYPE);
		if (conn.getAutoCommit() == true && !conn.isClosed())
			conn.close();
		return reObj;
	}

	/**
	 * 对PreparedStatement赋值
	 */
	public void fillPreparedStatement() throws SQLException {
		ParameterMetaData meta = ps.getParameterMetaData();
		for (int i = 1; i <= sqlFields.size(); i++) {
			if (null == sqlFields.get(i - 1))
				ps.setNull(i,meta.getParameterType(i));
			else if(sqlFields.get(i-1) instanceof Character)
				ps.setString(i, String.valueOf(sqlFields.get(i - 1)));
			else
				ps.setObject(i, sqlFields.get(i - 1));
		}
	}
	
	protected Object getFieldValue(Field field, Object object) {
		if(field.getType() == Character.class){
			char[] chars = ((String)object).toCharArray();
			if(null == chars || chars.length == 0)
				return null;
			else if(chars.length > 1)
				throw new IllegalArgumentException("Convert String to Character faliure,String length:"+chars.length);
			else 
				return chars[0];
		} else {
			return object;
		}
	}
}
